<?php 
namespace town\base;

class Store
{
    private static $obj = null;

    private $map = null;

    public function __construct()
    {
        $this->map = [];
    }

    private function init($data)
    {
        $this->map = $data;
    }

    private function set($key, $val)
    {
        $this->map[$key] = $val;
    }

    private function del($key)
    {
        unset($this->map[$key]);
        unset($_POST[$key]);
        unset($_GET[$key]);
    }

    private function val($key = null)
    {
        if ($key === null) {
            return array_merge($this->map, $_GET, $_POST);
        }
        $val = $this->map($key);
        if ($val) {
            return $val;
        }
        $val = $this->get($key);
        if ($val) {
            return $val;
        }
        $val = $this->post($key);
        if ($val) {
            return $val;
        }
        return null;
    }

    private function map($key = null)
    {
        if ($key === null) {
            return $this->map;
        }
        if ($this->map[$key]) {
            return $this->map[$key];
        }
        return null;
    }

    private function get($key = null)
    {
        if ($key === null) {
            return array_merge($this->map, $_GET);
        }
        if ($_GET[$key]) {
            return $_GET[$key];
        }
        return null;
    }

    private function post($key)
    {
        if ($key === null) {
            return $_POST;
        }
        if ($_POST[$key]) {
            return $_POST[$key];
        }
        return null;
    }

    public function __call($method, $arguments)
    {
        if (method_exists($this, $method)) {
            return call_user_func_array([$this, $method], $arguments);
        }
    }
    
    public static function __callStatic($method, $arguments)
    {
        $obj = static::singleton();
        if (method_exists($obj, $method)) {
            return call_user_func_array([$obj, $method], $arguments);
        }
    }

    public static function singleton()
    {
        if (static::$obj == null) {
            static::$obj = new static();
        }
        return static::$obj;
    }
}